package config

import (
	"encoding/json"
	"errors"
	"fmt"
	"os"
	"path/filepath"
	"sort"
	"strconv"
	"time"

	"github.com/RuiGuangServer/global"
)

type SunTimeData struct {
	Data map[string]map[string]struct {
		Sunrise string `json:"sunrise"`
		Sunset  string `json:"sunset"`
	} `json:"data"`
}

func GetSuntime() (int64, int64, error) {
	currentDay := time.Now().Day()

	// 从 atomic.Value 中获取当前值
	suntimeVal := global.Suntime.Load()

	if suntimeVal == nil || currentDay != suntimeVal.(global.Suntimes).Day {
		if err := initSunTime(); err != nil {
			return 0, 0, fmt.Errorf("failed to initialize suntime: %v", err)
		}

		suntimeVal = global.Suntime.Load()
		if suntimeVal == nil {
			return 0, 0, errors.New("suntime not initialized after update")
		}
	}

	// 类型断言获取 Suntimes
	suntime, ok := suntimeVal.(global.Suntimes)
	if !ok {
		return 0, 0, errors.New("invalid suntime type in storage")
	}

	return suntime.Sunrise, suntime.Sunset, nil
}

func initSunTime() error {
	if Config.AirPort == "" {
		return errors.New("airport configuration is missing")
	}
	dir, err := os.Getwd()
	if err != nil {
		return fmt.Errorf("failed to get working directory: %w", err)
	}

	files := fmt.Sprintf("suntimes_%v.json", Config.AirPort)
	fpath := filepath.Join(dir, "config", files)
	data, err := os.ReadFile(fpath)
	if err != nil {
		return fmt.Errorf("sun schedule data not found for airport %s: %w", Config.AirPort, err)
	}

	suntime, err := getDaySuntime(data)
	if err != nil {
		return fmt.Errorf("getDaySuntime error: %w", err)
	}

	// 使用 atomic.Value 存储
	global.Suntime.Store(suntime)

	return nil
}

func getDaySuntime(data []byte) (global.Suntimes, error) {
	var sunData SunTimeData
	if err := json.Unmarshal(data, &sunData); err != nil {
		return global.Suntimes{}, fmt.Errorf("failed to parse sun time data: %w", err)
	}

	year, m, day := time.Now().Date()
	month := int(m)

	monthStr := fmt.Sprintf("%v", month)
	dayData, monthExists := sunData.Data[monthStr]
	if !monthExists {
		return global.Suntimes{}, fmt.Errorf("no data found for month %d", month)
	}

	var days []int
	for dayStr := range dayData {
		if d, err := strconv.Atoi(dayStr); err == nil {
			days = append(days, d)
		}
	}
	sort.Ints(days)

	var sunrise, sunset int64
	var found bool
	loc, _ := time.LoadLocation("Asia/Shanghai")

	// 查找当前日期所在的区间
	for i := 0; i < len(days); i++ {
		startDay := days[i]
		var endDay int
		if i+1 < len(days) {
			endDay = days[i+1]
		} else {
			endDay = 32 // 设为下个月的第一天
		}

		if day >= startDay && day < endDay {
			dayStr := fmt.Sprintf("%v", startDay)
			times := dayData[dayStr]
			sr := fmt.Sprintf("%d-%02d-%02d %v:00", year, month, day, times.Sunrise)
			ss := fmt.Sprintf("%d-%02d-%02d %v:00", year, month, day, times.Sunset)
			srt, err := time.ParseInLocation("2006-01-02 15:04:05", sr, loc)
			if err != nil {
				return global.Suntimes{}, fmt.Errorf("failed to parse sunrise time: %w", err)
			}
			sst, err := time.ParseInLocation("2006-01-02 15:04:05", ss, loc)
			if err != nil {
				return global.Suntimes{}, fmt.Errorf("failed to parse sunset time: %w", err)
			}
			sunrise = srt.Unix()
			sunset = sst.Unix()
			found = true
			break
		}
	}
	if !found {
		return global.Suntimes{}, fmt.Errorf("no sun time data found for day %d in month %d", day, month)
	}

	// 返回结果
	return global.Suntimes{
		Day:     day,
		Sunrise: sunrise,
		Sunset:  sunset,
	}, nil
}

func GetClockType(time int64, class int) (int, error) {
	sr, ss, err := GetSuntime() // 获取当日日出(sr)、日落(ss)时间戳(秒)
	if err != nil {
		return -1, err
	}
	// 晨昏蒙影时间范围计算（日出前30分钟~日出，日落后30分钟）
	twilightBeforeSunrise := sr - 30*60
	twilightAfterSunset := ss + 30*60

	// class=0: 仅判断昼夜
	if class == 0 {
		if time >= sr && time <= ss {
			return 0, nil // 昼间
		}
		return 1, nil // 夜间
	}
	if class == 2 {
		if time >= sr && time <= ss {
			return Config.Luminosity + 0, nil // 昼间
		}
		return Config.Luminosity + 1, nil // 夜间
	}
	// class=1: 夜间时判断晨昏蒙影
	if time >= sr && time <= ss {
		return 0, nil // 昼间
	}

	// 夜间判断晨昏蒙影
	if (time >= twilightBeforeSunrise && time < sr) ||
		(time > ss && time <= twilightAfterSunset) {
		return 2, nil // 晨昏蒙影
	}

	return 1, nil // 普通夜间
}
